package com.zdp;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * <h1>全局过滤器校验请求头</h1>
 */
@Slf4j
@Component
public class GlobalCheckHeaderFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // 白名单
        if (checkWhiteListUrl(request.getURI().getPath())) {
            // 放行,执行路由
            return chain.filter(exchange);
        }

        // 从 HTTP Header 中寻找 key 为 Authorization
        String authorization = request.getHeaders().getFirst("Authorization");
        if (StringUtils.isBlank(authorization)) {
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        } else {
            if (authorization.contains("Bearer")) {
                authorization = StrUtil.removePrefix(authorization, "Bearer ");
                if (StringUtils.isBlank(authorization)) {
                    exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                } else {
                    // 放行,执行路由
                    return chain.filter(exchange);
                }
            }
        }
        return response.setComplete();
    }

    // 越大优先级越低
    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE + 1;
    }

    /**
     * <h2>校验是否是白名单接口，白名单接口直接放行不做验证token的过滤判断</h2>
     * */
    private static boolean checkWhiteListUrl(String url) {

        // 这里是把swagger的访问url都给放行, 判断url是否有以下关键字
        return StringUtils.containsAny(url,
                "/user/user-info-by/authentication-center/check/token", "swagger", "v2",
                "webjars", "doc.html");
    }

    public static void main(String[] args) {
        String url = "/gateway/resource-center/user/user-info-by/authentication-center/check/token";
        System.out.println(checkWhiteListUrl(url));
    }
}
